﻿using System;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using ScrapySharp.Extensions;
using ScrapySharp.Html.Dom;
using ScrapySharp.Network;

namespace HotCopperUserScanService
{
    public class HotCopperBrowser : IStockForumBrowser
    {
        private ScrapingBrowser _browser;

        public bool Login(string uname, string upassword, string testUrl)
        {
            _browser = new ScrapingBrowser();
            var loginDisclaimerPage = _browser.NavigateToPage(new Uri("http://hotcopper.com.au/login_disclaimer.asp?t=m"), HttpVerb.Post,
                new NameValueCollection() {{"uname", uname}, {"passwd", upassword}});

            if (loginDisclaimerPage.RawResponse.StatusCode == 200)
            {
                
                var ackResp = _browser.NavigateToPage(new Uri("http://hotcopper.com.au/login_disclaimer.asp"),
                    HttpVerb.Post,
                    new NameValueCollection()
                    {
                        {"redirect", ""},
                        {"postedfrom", "login_disclaimer"},
                        {"accepted", "true"}
                    });
                if (ackResp.RawResponse.StatusCode == 200 && !ackResp.Content.Contains("You need to log in to access this feature. It appears that you are not logged in"))
                {
                    var testPage = _browser.NavigateToPage(new Uri(testUrl), HttpVerb.Get);

                    return testPage.RawResponse.StatusCode == 200 && !testPage.Content.Contains("You need to log in to access this feature. It appears that you are not logged in");
                }


            }
            return false;
        }

        public bool LoginWithReq(string uname, string upassword)
        {
            _browser = new ScrapingBrowser();
            var resp = _browser.ExecuteRequest(new Uri("http://hotcopper.com.au/login_disclaimer.asp?t=m"), HttpVerb.Post,
                new NameValueCollection() { { "uname", uname }, { "passwd", upassword } });

            if ((resp as HttpWebResponse).StatusCode == HttpStatusCode.OK)
            {
                var ackResp = _browser.ExecuteRequest(new Uri("http://hotcopper.com.au/login_disclaimer.asp?t=m"),
                    HttpVerb.Post,
                    new NameValueCollection()
                    {
                        {"redirect", ""},
                        {"postedfrom", "login_disclaimer"},
                        {"accepted", "true"}
                    });
                var redirectResp = _browser.ExecuteRequest(new Uri("http://hotcopper.com.au/login_disclaimer.asp?t=m"), HttpVerb.Get, "");
                var defaultResp = _browser.ExecuteRequest(new Uri("http://hotcopper.com.au/default.asp"), HttpVerb.Get, "");

                return (ackResp as HttpWebResponse).StatusCode == HttpStatusCode.OK;
            }
            return false;
        }

        public void Logoff()
        {
            var ackResp = _browser.NavigateToPage(new Uri("http://hotcopper.com.au/user_logout.asp"));
        }

        public Webpage NavigateToPage(Uri uri)
        {
            var webPage = _browser.NavigateToPage(uri);

            var document = HDocument.Parse(webPage.Content);

            //Get the content of the message
            var postDetailItems = document.CssSelect("blockquote").CssSelect("p").Select(p => p.InnerText).ToArray();
            if (postDetailItems.Length == 0)
            {
                //may not have a paragraph tag - try passing without it
                postDetailItems = document.CssSelect("blockquote").Select(p => p.InnerText).ToArray();
            }
            var dateTimeElements = document.CssSelect("div.message-user-metadata").CssSelect("dd").Select(d => d.InnerText).ToArray();
            if (postDetailItems.Any() && dateTimeElements.Any())
            {
                //var selectedPosts = selected.Where(a => a.GetAttributeValue("href", "").Contains("hotcopper.com.au/post_single.asp")).Select(a => a.GetAttributeValue("href", ""));

                var postDateString = "";
                if (dateTimeElements.Length >= 2)
                    postDateString = string.Format("{0} {1}", dateTimeElements[0], dateTimeElements[1]);
                var postDateTime = DateTime.Now;
                if (!DateTime.TryParse(postDateString, out postDateTime))
                    postDateTime = DateTime.Now;

                //if it's a stock then there will be sentiment as well
                var codeItem = document.CssSelect("dl.ctrlUnit").CssSelect("label").Where(l => l.HasAttributes && l.GetAttributeValue("for", "") == "ctrl_tag_meta").Select(p => p.InnerText).ToArray();
                var firstPriceItem = document.CssSelect("dl.ctrlUnit").Where(dl => dl.CssSelect("label")
                                            .Any(l => l.HasAttributes && l.GetAttributeValue("for", "") == "ctrl_tag_meta"))
                                            .CssSelect("dd").Where(p => !string.IsNullOrEmpty(p.InnerText) && !p.InnerText.Equals("nbsp;"))
                                            .Select(p => p.InnerText).ToArray();

                return new Webpage() {
                    DateTime = postDateTime, 
                    Uri = uri.ToString(),
                    Code = codeItem.Any() ? codeItem[0].Replace("(ASX)", string.Empty).Trim() : string.Empty,
                    FirstPrice = firstPriceItem.Any() ? firstPriceItem[0] : string.Empty,
                    Content = string.Join(Environment.NewLine, postDetailItems).Replace("<br>", Environment.NewLine).Replace("</br>", string.Empty).Replace("<br />", string.Empty).Trim()};
            }

            return null;
        }

        public string GetPageContent(Uri uri)
        {
            var webPage = _browser.NavigateToPage(uri);
            return webPage.Content;
        }
    }
}